home *** CD-ROM | disk | FTP | other *** search
/ Turnbull China Bikeride / Turnbull China Bikeride - Disc 2.iso / STUTTGART / LANG / C / LIB / UNIXLIB37B / !UnixLib37 / src / stdio / c / getdelim < prev    next >
Text File  |  1996-11-09  |  3KB  |  115 lines

  1. /****************************************************************************
  2.  *
  3.  * $Source: /unixb/home/unixlib/source/unixlib37/src/stdio/c/RCS/getdelim,v $
  4.  * $Date: 1996/11/06 22:01:42 $
  5.  * $Revision: 1.1 $
  6.  * $State: Rel $
  7.  * $Author: unixlib $
  8.  *
  9.  * $Log: getdelim,v $
  10.  * Revision 1.1  1996/11/06 22:01:42  unixlib
  11.  * Initial revision
  12.  *
  13.  ***************************************************************************/
  14.  
  15. /* c.getdelim. Written by Nick Burrett, 27 October 1996.  */
  16.  
  17. static const char rcs_id[] = "$Id: getdelim,v 1.1 1996/11/06 22:01:42 unixlib Rel $";
  18.  
  19. #include <stddef.h>
  20. #include <stdio.h>
  21. #include <stdlib.h>
  22. #include <string.h>
  23. #include <limits.h>
  24. #include <sys/types.h>
  25.  
  26. /* Read up to (and including) a terminator from stream into *lineptr
  27.    (and null-terminate it). *lineptr is a pointer returned from malloc
  28.    (or NULL), pointing to *n charcters of space. It is realloc'd as
  29.    necessary. Returns the number of characters read (not including the
  30.    null terminator), or -1 on error or EOF.  */
  31.  
  32. ssize_t
  33. getdelim (char **lineptr, size_t *n, int terminator, FILE *stream)
  34. {
  35.   char *line, *p;
  36.   size_t size, copy;
  37.  
  38.   /* Validity check.  */
  39.   if (stream == NULL || lineptr == NULL || n == NULL)
  40.     {
  41.       errno = EINVAL;
  42.       return -1;
  43.     }
  44.  
  45.   if (ferror (stream))
  46.     return -1;
  47.  
  48.   /* Make sure we have a line buffer to start with.  */
  49.   if (*lineptr == NULL || *n < 2)
  50.     {
  51.       line = realloc (*lineptr, MAX_CANON);
  52.       if (line == NULL)
  53.     return -1;
  54.       *lineptr = line;
  55.       *n = MAX_CANON;
  56.     }
  57.  
  58.   line = *lineptr;
  59.   size = *n;
  60.  
  61.   copy = size;
  62.   p = line;
  63.  
  64.   for (;;)
  65.     {
  66.       size_t len;
  67.  
  68.       /* Get the characters, byte by byte, into buffer line until
  69.          we reach the termination character, or we run out of buffer
  70.          space.  */
  71.       while (--copy > 0)
  72.     {
  73.       int c = getc (stream);
  74.       if (c == EOF)
  75.         {
  76.           if (p == *lineptr)
  77.             return -1;
  78.             /* Return a partial line since we got an error in the middle.  */
  79.             *p = '\0';
  80.             return p - *lineptr;
  81.         }
  82.       else if ((*p++ = c) == terminator)
  83.         {
  84.           *p = '\0';
  85.           return p - *lineptr;
  86.         }
  87.     }
  88.  
  89.       /* Need to enlarge the line buffer.  */
  90.       len = p - line;
  91.       size *= 2;
  92.       line = realloc (line, size);
  93.       /* Bit of a memory problem, break out of while() and return
  94.          what we managed to obtain.  */
  95.       if (line == NULL)
  96.     break;
  97.       *lineptr = line;
  98.       *n = size;
  99.       p = line + len;
  100.       copy = size - len;
  101.     }
  102.  
  103.   if (p == *lineptr)
  104.     return -1;
  105.  
  106.   *p = '\0';
  107.   return p - *lineptr;
  108. }
  109.  
  110. ssize_t
  111. getline (char **lineptr, size_t *n, FILE *stream)
  112. {
  113.   return getdelim (lineptr, n, '\n', stream);
  114. }
  115.